package com.csu.cphone.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.csu.common.exception.WebException;
import com.csu.common.sms.SMSSender;
import com.csu.common.utils.JsonUtil;
import com.csu.common.utils.RedisUtil;
import com.csu.cphone.constants.RedisKey;
import com.csu.cphone.dao.MaintainOrderMapper;
import com.csu.cphone.dao.ProducerMapper;
import com.csu.cphone.dao.RecycleOrderMapper;
import com.csu.cphone.pojo.MaintainOrderPojo;
import com.csu.cphone.pojo.ProducerPojo;
import com.csu.cphone.pojo.RecycleOrderPojo;
import com.csu.cphone.service.OrderStaskService;
import com.csu.cphone.service.UserService;
import com.csu.cphone.vo.OrderCacheInfo;

/**
 * @项目名称：cphone
 * @类名称：OrderStaskServiceImpl
 * @类描述：
 * @创建人：Tangc
 * @创建时间：2017年12月16日 上午10:00:44
 * @company:
 */
@Component
@Service
@EnableScheduling
public class OrderStaskServiceImpl implements OrderStaskService
{

    @Autowired
    private UserService userService;

    @Autowired
    private ProducerMapper producerMapper;

    @Autowired
    private MaintainOrderMapper maintainOrderMapper;

    @Autowired
    private RecycleOrderMapper recycleOrderMapper;

    private static final Logger logger = Logger.getLogger(OrderStaskServiceImpl.class);

    private static final String IS_NOT_AUTO_ALLOC = "true";

    /**
     * @description 11分钟检查一次订单并且通知
     * @author TangC
     * @date 2017年12月16日 上午10:27:26
     */
    @Override
    @Scheduled(initialDelay = 1000, fixedRate = 1000 * 60 * 3)
    public void notifyOrders()
    {
        logger.debug("excute time task notify order");
        List<MaintainOrderPojo> maintailOrders = maintainOrderMapper.selectByStatus(1);
        for (MaintainOrderPojo order : maintailOrders)
        {
            int producerId = order.getProducerId();
            ProducerPojo producer = producerMapper.selectById(producerId);
            String number = producer.getNumber();
            List<String> maintainSn = RedisUtil.getRedisDb().lrange(RedisKey.WAITING_MAINTAIM_ORDER + number, 0, -1);
            String sn = order.getSerialNumber();
            if (maintainSn.contains(sn))
            {
                SMSSender.sendSMSByType(number, null, 1);
                RedisUtil.getRedisDb().lrem(RedisKey.WAITING_MAINTAIM_ORDER, 0, sn);
            }

        }
        List<RecycleOrderPojo> recycleOrders = recycleOrderMapper.selectByStatus(1);
        for (RecycleOrderPojo order : recycleOrders)
        {
            int producerId = order.getProducerId();
            ProducerPojo producer = producerMapper.selectById(producerId);
            String number = producer.getNumber();

            List<String> recycleSn = RedisUtil.getRedisDb().lrange(RedisKey.WAITING_RECYCLE_ORDER + number, 0, -1);
            String sn = order.getSerialNumber();
            if (recycleSn.contains(sn))
            {
                SMSSender.sendSMSByType(number, null, 2);
                RedisUtil.getRedisDb().lrem(RedisKey.WAITING_RECYCLE_ORDER, 0, sn);
            }

        }
    }

    /**
     * @description 3分钟检查一次订单并且分配
     * @author TangC
     * @date 2017年12月16日 上午10:27:26
     */
    @Override
    @Scheduled(initialDelay = 1000, fixedRate = 1000 * 60 * 1)
    public void allocOrders()
    {
        logger.debug("excute time task alloc order");
        allocOrder(1);
        allocOrder(2);
        addOrderToQueue();
    }

    /**
     * @description
     * @author TangC
     * @date 2017年12月21日 上午8:49:30
     */
    private void addOrderToQueue()
    {
        List<MaintainOrderPojo> maintainOrders = maintainOrderMapper.selectByStatus(0);
        if (!CollectionUtils.isEmpty(maintainOrders))
        {
            for (MaintainOrderPojo maintainOrder : maintainOrders)
            {
                OrderCacheInfo orderInfo = new OrderCacheInfo();
                String position = RedisUtil.getRedisDb().hget(RedisKey.ORDER_POSITION, orderInfo.getSn());
                if (position == null)
                {
                    return;
                }
                orderInfo.setPosition(position);
                orderInfo.setSn(maintainOrder.getSerialNumber());

                String orderJson = JsonUtil.toJSONString(orderInfo);
                RedisUtil.getRedisDb().lpush(RedisKey.WAITING_ORDER_QUEUE + "maintain", orderJson);
                RedisUtil.getRedisDb().hdel(RedisKey.ORDER_POSITION, orderInfo.getSn());
            }
        }

        List<RecycleOrderPojo> recycleOrders = recycleOrderMapper.selectByStatus(0);
        if (!CollectionUtils.isEmpty(recycleOrders))
        {
            for (RecycleOrderPojo recycleOrder : recycleOrders)
            {
                OrderCacheInfo orderInfo = new OrderCacheInfo();
                String position = RedisUtil.getRedisDb().hget(RedisKey.ORDER_POSITION, orderInfo.getSn());
                if (position == null)
                {
                    return;
                }
                orderInfo.setPosition(position);
                orderInfo.setSn(recycleOrder.getSerialNumber());

                String orderJson = JsonUtil.toJSONString(orderInfo);
                RedisUtil.getRedisDb().lpush(RedisKey.WAITING_ORDER_QUEUE + "recycle", orderJson);
                RedisUtil.getRedisDb().hdel(RedisKey.ORDER_POSITION, orderInfo.getSn());
            }
        }

    }

    /**
     * @description
     * @author TangC
     * @date 2017年12月16日 上午10:51:28
     */

    private void allocOrder(Integer service)
    {
        String order = null;
        if (service == 1)
        {
            order = RedisUtil.getRedisDb().rpop(RedisKey.WAITING_ORDER_QUEUE + "maintain");
        }
        else if (service == 2)
        {
            order = RedisUtil.getRedisDb().rpop(RedisKey.WAITING_ORDER_QUEUE + "recycle");
        }
        if (order == null)
        {
            // 无订单返回
            return;
        }
        OrderCacheInfo orderInfo = JsonUtil.toObject(order, OrderCacheInfo.class);
        String position = orderInfo.getPosition();
        ProducerPojo producer = getNearListProduerId(position, service);
        if (producer == null || producer.getNumber() == null)
        {
            // 找不到服务方,放回去
            if (service == 1)
            {
                RedisUtil.getRedisDb().lpush(RedisKey.WAITING_ORDER_QUEUE + "maintain", order);
            }
            else if (service == 2)
            {
                RedisUtil.getRedisDb().lpush(RedisKey.WAITING_ORDER_QUEUE + "recycle", order);
            }
            RedisUtil.getRedisDb().hdel(RedisKey.ORDER_POSITION, orderInfo.getSn());
            return;
        }

        String sn = orderInfo.getSn();

        int update = updateOrder(sn, producer.getId(), service);
        if (update == 1)
        {
            String number = producer.getNumber();
            String waitingKey = "";
            if (service == 1)
            {
                waitingKey = RedisKey.WAITING_MAINTAIM_ORDER;
            }
            else if (service == 2)
            {
                waitingKey = RedisKey.WAITING_RECYCLE_ORDER;
            }
            RedisUtil.getRedisDb().lpush(waitingKey + number, sn);
            sendMessage(sn, service);
        }
    }

    /**
     * @description
     * @author TangC
     * @date 2017年12月26日 下午5:45:22
     * @param sn
     * @param service
     */
    private void sendMessage(String sn, Integer service)
    {
        String number = null;
        if (service == 1)
        {
            number = maintainOrderMapper.selectNumberBySn(sn);
        }
        else if (service == 2)
        {
            number = recycleOrderMapper.selectNumberBySn(sn);
        }
        if (number != null)
        {
            SMSSender.sendSMSByType(number, null, 3);
        }
    }

    /**
     * @description
     * @author TangC
     * @date 2017年12月16日 上午11:10:51
     * @param sn
     * @param id
     * @param service
     */
    private int updateOrder(String sn, Integer producerId, Integer service)
    {
        if (service == 1)
        {
            MaintainOrderPojo order = maintainOrderMapper.selectBySn(sn);
            if (order.getStatus() != 0)
            {
                return 0;
            }
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("serialNumber", sn);
            map.put("producerId", producerId);
            map.put("status", 1);
            return maintainOrderMapper.updateProducer(map);
        }
        else if (service == 2)
        {
            RecycleOrderPojo order = recycleOrderMapper.selectBySn(sn);
            if (order.getStatus() != 0)
            {
                return 0;
            }
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("serialNumber", sn);
            map.put("producerId", producerId);
            map.put("status", 1);
            return recycleOrderMapper.updateProducer(map);
        }
        return 0;
    }

    /**
     * @description
     * @author TangC
     * @date 2017年12月9日 下午10:22:32
     * @param position
     * @return
     * @throws WebException
     */
    private ProducerPojo getNearListProduerId(String position, Integer service)
    {
        ProducerPojo producer = null;
        if ("true".equals(IS_NOT_AUTO_ALLOC))
        {
            producer = userService.getProducerByNumber("18150533737");
            if (producer != null)
            {
                return producer;
            }
        }

        String[] positions = position.split(",");
        String latString = positions[0];
        String lngString = positions[1];

        Double lat = Double.valueOf(latString);
        Double lng = Double.valueOf(lngString);

        return userService.getNearProducer(lat, lng, service);
    }
}
